import sys
import time

from example.Strategy import Strategy

sys.path.append('.')
sys.path.append('..')
sys.path.append('../../..')
sys.path.append('../../../..')

import pandas as pd

from quant import data_utils
from quant.match import Match
from datetime import datetime, timedelta
from dateutil.parser import parse
import calendar

total_ev = 0
total_bet = 0

DATA_FILE = "../data/20240924.csv"
DAYS = 365
COEF = 1
NOT_BETTING = 99
VERY_BIG_RATIO = 999


class FootBallPredict:
    def __init__(self):
        # 预处理数据
        self.total_bet_amount = 0
        self.total_bet_count = 0
        self.total_bonus_amount = 0
        self.total_bonus_count = 0
        self.total_rangqiu_bet_amount = 0
        self.total_rangqiu_bet_count = 0
        self.total_rangqiu_bonus_amount = 0
        self.total_rangqiu_bonus_count = 0
        self.total_match_count = 0

        self.total_goal_bet_amount = 0
        self.total_goal_bet_count = 0
        self.total_goal_bonus_amount = 0
        self.total_goal_bonus_count = 0

        base_df = pd.read_csv(DATA_FILE, encoding="UTF-8",
                              usecols=["场次", "比赛时间", "联赛", "主客场", "赛果", "让球赛果", "胜临", "平临",
                                       "负临", "让胜临", "让平临", "让负临", "让球", "总进球",
                                       "0临", "1临", "2临", "3临", "4临", "5临", "6临", "7临", "总进球赔率", "平平",
                                       "平平临", "半全场"],
                              header=0,
                              low_memory=False
                              )
        # base_df = base_df.dropna()
        base_df['比赛时间'] = pd.to_datetime(base_df['比赛时间'])
        self.base_df = base_df
        self.init_data()

    def init_data(self):
        self.total_bet_amount = 0
        self.total_bet_count = 0
        self.total_bonus_amount = 0
        self.total_bonus_count = 0
        self.total_rangqiu_bet_amount = 0
        self.total_rangqiu_bet_count = 0
        self.total_rangqiu_bonus_amount = 0
        self.total_rangqiu_bonus_count = 0
        self.total_match_count = 0

    def grid_search(self):
        error_margin = [0.05, 0.10, 0.15]
        nice_percent = [110, 115, 120]
        min_same_count = [15, 20, 25]

        best_args1 = []
        best_args2 = []
        worst_args1 = []
        worst_args2 = []
        max_ev1 = 0
        min_ev1 = 0
        max_ev2 = 0
        min_ev2 = 0
        current_time = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime())
        logfile = f'log-{current_time}.txt'
        for e in error_margin:
            for n in nice_percent:
                for s in min_same_count:
                    start_date = "2024-01-01"
                    end_date = "2024-08-01"
                    dates = pd.date_range(start=start_date, end=end_date, freq="D")

                    self.total_bet_amount = 0
                    self.total_bet_count = 0
                    self.total_bonus_amount = 0
                    self.total_bonus_count = 0
                    self.total_rangqiu_bet_amount = 0
                    self.total_rangqiu_bet_count = 0
                    self.total_rangqiu_bonus_amount = 0
                    self.total_rangqiu_bonus_count = 0

                    for d in dates:
                        self.predict(dt=d.strftime("%Y-%m-%d"), error_margin=e, nice_percent=n, min_same_count=s,
                                     print_log=False)

                    ev1 = round(self.total_bonus_amount - self.total_bet_amount, 2)
                    ev2 = round(self.total_rangqiu_bonus_amount - self.total_rangqiu_bet_amount, 2)
                    if ev1 > max_ev1:
                        max_ev1 = ev1
                        best_args1 = [e, n, s]

                    if ev1 < min_ev1:
                        min_ev1 = ev1
                        worst_args1 = [e, n, s]

                    if ev2 < min_ev2:
                        min_ev2 = ev2
                        worst_args2 = [e, n, s]
                    str = (f"{start_date},{end_date},{e},{n},{s},{self.total_bet_amount},"
                           f"{self.total_rangqiu_bet_amount},{ev1},{ev2}")
                    with open(logfile, 'a') as file:
                        file.writelines(str + "\n")

                    print(str)

    def ev_grid_search(self):
        error_margin = [0.05, 0.06, 0.07, 0.08, 0.09, 0.1, 0.11, 0.12, 0.13, 0.14, 0.15]
        nice_percent = [106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130]
        min_same_count = [10, 15, 20, 25, 30]
        stratrgies = []
        count = 1
        period = 365
        start_date = "2024-08-07"
        for i in range(0, len(error_margin)):
            for j in range(0, len(nice_percent)):
                for k in range(0, len(min_same_count)):
                    stratrgies.append(
                        {"name": f'{count}号', "error_margin": error_margin[i],
                         "nice_percent": nice_percent[j], "min_same_count": min_same_count[k]})
                    count += 1

        for i in range(0, len(stratrgies)):
            strategy = stratrgies[i]
            self.init_data()
            backtest_result = self.backtest_period(start_date, period, strategy)
            str = (f"{strategy['name']} {start_date},{strategy['error_margin']},{strategy['nice_percent']}"
                   f",{strategy['min_same_count']},{self.total_bet_amount},"
                   f"{self.total_rangqiu_bet_amount},{backtest_result['ev']},{backtest_result['rangqiu_ev']}")
            current_time = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime())
            with open(f'log-{current_time}.txt', 'a') as file:
                file.writelines(str + "\n")
            print(str)

    def prepare_options(self, match, options):
        options["game_date"] = match.game_date
        if (options['use_league']):
            options['league'] = match.league

        if (options['use_rangqiu_num']):
            options['rangqiu_num'] = int(match.rangqiu)

        if (options['use_win']):
            options['win_low'] = round(float(match.win) * (1 - options['margin_of_error']), 2)
            options['win_high'] = round(float(match.win) * (1 + options['margin_of_error']), 2)

        if (options['use_draw']):
            options['draw_low'] = round(float(match.draw) * (1 - options['margin_of_error']), 2)
            options['draw_high'] = round(float(match.draw) * (1 + options['margin_of_error']), 2)

        if (options['use_lose']):
            options['lose_low'] = round(float(match.lose) * (1 - options['margin_of_error']), 2)
            options['lose_high'] = round(float(match.lose) * (1 + options['margin_of_error']), 2)

        if (options['use_rangqiu_win']):
            options['rangqiu_win_low'] = round(float(match.rangqiu_win) * (1 - options['margin_of_error']), 2)
            options['rangqiu_win_high'] = round(float(match.rangqiu_win) * (1 + options['margin_of_error']), 2)

        if (options['use_rangqiu_draw']):
            options['rangqiu_draw_low'] = round(float(match.rangqiu_draw) * (1 - options['margin_of_error']), 2)
            options['rangqiu_draw_high'] = round(float(match.rangqiu_draw) * (1 + options['margin_of_error']), 2)

        if (options['use_rangqiu_lose']):
            options['rangqiu_lose_low'] = round(float(match.rangqiu_lose) * (1 - options['margin_of_error']), 2)
            options['rangqiu_lose_high'] = round(float(match.rangqiu_lose) * (1 + options['margin_of_error']), 2)

        return options

    def prepare_goal_options(self, match, options):
        options["game_date"] = match.game_date
        if (options['use_league']):
            options['league'] = match.league

        if (options['use_rangqiu_num']):
            options['rangqiu_num'] = int(match.rangqiu)

        if (options['use_win']):
            options['win_low'] = round(float(match.win) * (1 - options['margin_of_error']), 2)
            options['win_high'] = round(float(match.win) * (1 + options['margin_of_error']), 2)

        if (options['use_draw']):
            options['draw_low'] = round(float(match.draw) * (1 - options['margin_of_error']), 2)
            options['draw_high'] = round(float(match.draw) * (1 + options['margin_of_error']), 2)

        if (options['use_lose']):
            options['lose_low'] = round(float(match.lose) * (1 - options['margin_of_error']), 2)
            options['lose_high'] = round(float(match.lose) * (1 + options['margin_of_error']), 2)

        if (options['use_rangqiu_win']):
            options['rangqiu_win_low'] = round(float(match.rangqiu_win) * (1 - options['margin_of_error']), 2)
            options['rangqiu_win_high'] = round(float(match.rangqiu_win) * (1 + options['margin_of_error']), 2)

        if (options['use_rangqiu_draw']):
            options['rangqiu_draw_low'] = round(float(match.rangqiu_draw) * (1 - options['margin_of_error']), 2)
            options['rangqiu_draw_high'] = round(float(match.rangqiu_draw) * (1 + options['margin_of_error']), 2)

        if (options['use_rangqiu_lose']):
            options['rangqiu_lose_low'] = round(float(match.rangqiu_lose) * (1 - options['margin_of_error']), 2)
            options['rangqiu_lose_high'] = round(float(match.rangqiu_lose) * (1 + options['margin_of_error']), 2)

        if (options['use_goal_0']):
            options['goal_0_low'] = round(float(match.goal_0) * (1 - options['margin_of_error']), 2)
            options['goal_0_high'] = round(float(match.goal_0) * (1 + options['margin_of_error']), 2)

        if (options['use_goal_1']):
            options['goal_1_low'] = round(float(match.goal_1) * (1 - options['margin_of_error']), 2)
            options['goal_1_high'] = round(float(match.goal_1) * (1 + options['margin_of_error']), 2)

        if (options['use_goal_2']):
            options['goal_2_low'] = round(float(match.goal_2) * (1 - options['margin_of_error']), 2)
            options['goal_2_high'] = round(float(match.goal_2) * (1 + options['margin_of_error']), 2)

        if (options['use_goal_3']):
            options['goal_3_low'] = round(float(match.goal_3) * (1 - options['margin_of_error']), 2)
            options['goal_3_high'] = round(float(match.goal_3) * (1 + options['margin_of_error']), 2)

        if (options['use_goal_4']):
            options['goal_4_low'] = round(float(match.goal_4) * (1 - options['margin_of_error']), 2)
            options['goal_4_high'] = round(float(match.goal_4) * (1 + options['margin_of_error']), 2)

        if (options['use_goal_5']):
            options['goal_5_low'] = round(float(match.goal_5) * (1 - options['margin_of_error']), 2)
            options['goal_5_high'] = round(float(match.goal_5) * (1 + options['margin_of_error']), 2)

        if (options['use_goal_6']):
            options['goal_6_low'] = round(float(match.goal_6) * (1 - options['margin_of_error']), 2)
            options['goal_6_high'] = round(float(match.goal_6) * (1 + options['margin_of_error']), 2)

        if (options['use_goal_7']):
            options['goal_7_low'] = round(float(match.goal_7) * (1 - options['margin_of_error']), 2)
            options['goal_7_high'] = round(float(match.goal_7) * (1 + options['margin_of_error']), 2)

        return options

    def query_matches(self, options):
        df = self.base_df.copy()
        df["让球"] = df["让球"].astype(int)
        # df["总进球"] = df["总进球"].astype(int)

        start_date = (datetime.strptime(options["game_date"], '%Y-%m-%d') + timedelta(days=-DAYS)).strftime('%Y-%m-%d')
        end_date = (datetime.strptime(options["game_date"], '%Y-%m-%d') + timedelta(days=-2)).strftime('%Y-%m-%d')

        df['比赛时间'] = pd.to_datetime(df['比赛时间'])
        df = df[(df['比赛时间'] >= start_date) & (df['比赛时间'] <= end_date)]
        if options["use_league"]:
            df = df[df['联赛'] == options["league"]]

        df['让球赛果'] = df['让球赛果'].apply(
            lambda x: x.replace("让胜", "胜").replace("让平", "平").replace("让负", "负"))

        if options["use_rangqiu_num"]:
            df = df[(df['让球'] == options["rangqiu_num"])]

        if options["use_win"]:
            df = df[(df['胜临'] >= options["win_low"]) & (df['胜临'] <= options["win_high"])]

        if options["use_draw"]:
            df = df[(df['平临'] >= options["draw_low"]) & (df['平临'] <= options["draw_high"])]

        if options["use_lose"]:
            df = df[(df['负临'] >= options["lose_low"]) & (df['负临'] <= options["lose_high"])]

        if options["use_rangqiu_win"]:
            df = df[(df['让胜临'] >= options["rangqiu_win_low"]) & (df['让胜临'] <= options["rangqiu_win_high"])]

        if options["use_rangqiu_draw"]:
            df = df[(df['让平临'] >= options["rangqiu_draw_low"]) & (df['让平临'] <= options["rangqiu_draw_high"])]

        if options["use_rangqiu_lose"]:
            df = df[(df['让负临'] >= options["rangqiu_lose_low"]) & (df['让负临'] <= options["rangqiu_lose_high"])]

        if "use_goal_0" in options.keys() and options["use_goal_0"]:
            df = df[(df['0临'] >= options["goal_0_low"]) & (df['0临'] <= options["goal_0_high"])]

        if "use_goal_1" in options.keys() and options["use_goal_1"]:
            df = df[(df['1临'] >= options["goal_1_low"]) & (df['1临'] <= options["goal_1_high"])]

        if "use_goal_2" in options.keys() and options["use_goal_2"]:
            df = df[(df['2临'] >= options["goal_2_low"]) & (df['2临'] <= options["goal_2_high"])]

        if "use_goal_3" in options.keys() and options["use_goal_3"]:
            df = df[(df['3临'] >= options["goal_3_low"]) & (df['3临'] <= options["goal_3_high"])]

        if "use_goal_4" in options.keys() and options["use_goal_4"]:
            df = df[(df['4临'] >= options["goal_4_low"]) & (df['4临'] <= options["goal_4_high"])]

        if "use_goal_5" in options.keys() and options["use_goal_5"]:
            df = df[(df['5临'] >= options["goal_5_low"]) & (df['5临'] <= options["goal_5_high"])]

        if "use_goal_6" in options.keys() and options["use_goal_6"]:
            df = df[(df['6临'] >= options["goal_6_low"]) & (df['6临'] <= options["goal_6_high"])]

        if "use_goal_7" in options.keys() and options["use_goal_7"]:
            df = df[(df['7临'] >= options["goal_7_low"]) & (df['7临'] <= options["goal_7_high"])]

        return df

    total_bet_amount = 0
    total_bet_count = 0
    total_bonus_amount = 0
    total_bonus_count = 0

    total_rangqiu_bet_amount = 0
    total_rangqiu_bet_count = 0
    total_rangqiu_bonus_amount = 0
    total_rangqiu_bonus_count = 0

    def read_matches(self, dt):
        df = self.base_df.copy()
        df = df[(df['比赛时间'] == dt)]
        df['赛果'] = df['赛果'].apply(lambda x: 3 if x == "胜" else x)
        df['赛果'] = df['赛果'].apply(lambda x: 1 if x == "平" else x)
        df['赛果'] = df['赛果'].apply(lambda x: 0 if x == "负" else x)
        df['让球赛果'] = df['让球赛果'].apply(lambda x: 3 if x == "胜" else x)
        df['让球赛果'] = df['让球赛果'].apply(lambda x: 1 if x == "平" else x)
        df['让球赛果'] = df['让球赛果'].apply(lambda x: 0 if x == "负" else x)
        df['让球赛果'] = df['让球赛果'].apply(lambda x: 3 if x == "让胜" else x)
        df['让球赛果'] = df['让球赛果'].apply(lambda x: 1 if x == "让平" else x)
        df['让球赛果'] = df['让球赛果'].apply(lambda x: 0 if x == "让负" else x)

        matches = {}
        for index, row in df.iterrows():
            match = Match()
            match.no = row['场次']
            match.league = row['联赛']
            match.home_team = row['主客场'].split("VS")[0]
            match.away_team = row['主客场'].split("VS")[1]
            match.rangqiu = row['让球']
            match.win = row['胜临']
            match.draw = row['平临']
            match.lose = row['负临']
            match.rangqiu_win = row['让胜临']
            match.rangqiu_draw = row['让平临']
            match.rangqiu_lose = row['让负临']
            match.result = row['赛果']
            match.rangqiu_result = row['让球赛果']
            match.goal_0 = row['0临']
            match.goal_1 = row['1临']
            match.goal_2 = row['2临']
            match.goal_3 = row['3临']
            match.goal_4 = row['4临']
            match.goal_5 = row['5临']
            match.goal_6 = row['6临']
            match.goal_7 = row['7临']
            match.goal_result = row['总进球']
            match.goal_ratio = row['总进球赔率']
            match.dd = row['平平临']
            match.half_result = row['半全场']
            match.game_date = dt
            matches[match.no] = match
        return matches

    def predict(self, dt="", use_online_data=False, use_online_data_day=0, error_margin=0.05, nice_percent=125,
                min_same_count=10, print_log=True):
        match_bet_amount = 0
        match_bet_count = 0
        match_bonus_amount = 0
        match_bonus_count = 0
        match_rangqiu_bet_amount = 0
        match_rangqiu_bet_count = 0
        match_rangqiu_bonus_amount = 0
        match_rangqiu_bonus_count = 0

        match_goal_bet_amount = 0
        match_goal_bonus = 0

        predict_history = []
        predict_result_history = []

        predicts = {}

        if use_online_data:
            matches = data_utils.read_matches(use_online_data_day)
        else:
            matches = self.read_matches(dt)
        if (not matches or len(matches) == 0):
            return

        self.total_match_count += len(matches)

        for k in matches.keys():
            match = matches[k]
            predict_result, predict_rangqiu_result, backtest_results = self.predict_match(match, error_margin,
                                                                                          nice_percent, min_same_count)
            predicts[match.game_date + " " + match.no] = [predict_result, predict_rangqiu_result]

            if predict_result == NOT_BETTING and predict_rangqiu_result == predict_result and not backtest_results:
                if (print_log):
                    # print(f"{match.no} 不下注")
                    predict_history.append(f"{match.no} 不下注")
                continue

            if predict_result != NOT_BETTING:
                match_bet_amount = 1
                match_bet_count = 1
                match_bonus_amount = 0
                match_bonus_count = 0
                if (predict_result == int(match.result)):
                    match_bonus_count = 1
                    if (predict_result == 0):
                        match_bonus_amount = float(match.lose)
                    if (predict_result == 1):
                        match_bonus_amount = float(match.draw)
                    if (predict_result == 3):
                        match_bonus_amount = float(match.win)
                self.total_bet_amount += match_bet_amount
                self.total_bet_count += match_bet_count
                self.total_bonus_amount += match_bonus_amount
                self.total_bonus_count += match_bonus_count

            if predict_rangqiu_result != NOT_BETTING:
                match_rangqiu_bet_amount = 1
                match_rangqiu_bet_count = 1
                match_rangqiu_bonus_amount = 0
                match_rangqiu_bonus_count = 0
                if (predict_rangqiu_result == int(match.rangqiu_result)):
                    match_rangqiu_bonus_count = 1
                    if (predict_rangqiu_result == 0):
                        match_rangqiu_bonus_amount = float(match.rangqiu_lose)
                    if (predict_rangqiu_result == 1):
                        match_rangqiu_bonus_amount = float(match.rangqiu_draw)
                    if (predict_rangqiu_result == 3):
                        match_rangqiu_bonus_amount = float(match.rangqiu_win)
                self.total_rangqiu_bet_amount += match_rangqiu_bet_amount
                self.total_rangqiu_bet_count += match_rangqiu_bet_count
                self.total_rangqiu_bonus_amount += match_rangqiu_bonus_amount
                self.total_rangqiu_bonus_count += match_rangqiu_bonus_count

            match_no = f'\033[31m{match.no}\033[0m'
            same_count = backtest_results["same_count"]

            win_count = backtest_results["win_count"]
            draw_count = backtest_results["draw_count"]
            lose_count = backtest_results["lose_count"]

            wins_percent = backtest_results["wins_percent"]
            draws_percent = backtest_results["draws_percent"]
            losses_percent = backtest_results["losses_percent"]

            win_payback_percent = backtest_results["win_payback_percent"]
            draw_payback_percent = backtest_results["draw_payback_percent"]
            lose_payback_percent = backtest_results["lose_payback_percent"]

            rangqiu_win_count = backtest_results["rangqiu_win_count"]
            rangqiu_draw_count = backtest_results["rangqiu_draw_count"]
            rangqiu_lose_count = backtest_results["rangqiu_lose_count"]

            rangqiu_wins_percent = backtest_results["rangqiu_wins_percent"]
            rangqiu_draws_percent = backtest_results["rangqiu_draws_percent"]
            rangqiu_loses_percent = backtest_results["rangqiu_loses_percent"]

            rangqiu_win_payback_percent = backtest_results["rangqiu_win_payback_percent"]
            rangqiu_draw_payback_percent = backtest_results["rangqiu_draw_payback_percent"]
            rangqiu_lose_payback_percent = backtest_results["rangqiu_lose_payback_percent"]

            win_payback_percent_str = f'\033[31m{win_payback_percent}\033[0m' if win_payback_percent > nice_percent else win_payback_percent
            draw_payback_percent_str = f'\033[31m{draw_payback_percent}\033[0m' if draw_payback_percent > nice_percent else draw_payback_percent
            lose_payback_percent_str = f'\033[31m{lose_payback_percent}\033[0m' if lose_payback_percent > nice_percent else lose_payback_percent
            rangqiu_win_payback_percent_str = f'\033[31m{rangqiu_win_payback_percent}\033[0m' if rangqiu_win_payback_percent > nice_percent else rangqiu_win_payback_percent
            rangqiu_draw_payback_percent_str = f'\033[31m{rangqiu_draw_payback_percent}\033[0m' if rangqiu_draw_payback_percent > nice_percent else rangqiu_draw_payback_percent
            rangqiu_lose_payback_percent_str = f'\033[31m{rangqiu_lose_payback_percent}\033[0m' if rangqiu_lose_payback_percent > nice_percent else rangqiu_lose_payback_percent

            same_count = f'\033[31m{same_count}\033[0m' if same_count > min_same_count else same_count
            if (print_log):
                print(
                    f'{match_no} {match.endtime} {match.league} {"{:<5}".format(match.home_team)} vs {"{:>5}".format(match.away_team)} '
                    f'让球:{match.rangqiu}\n'
                    f'    历史同赔: {same_count} '
                    f'  (胜:{win_count}|{wins_percent}%|{win_payback_percent_str}%) '
                    f'(平:{draw_count}|{draws_percent}%|{draw_payback_percent_str}%) '
                    f'(负:{lose_count}|{losses_percent}%|{lose_payback_percent_str}%)  (赛果:{match.result})       '
                    f'(让胜:{rangqiu_win_count}|{rangqiu_wins_percent}%|{rangqiu_win_payback_percent_str}%) '
                    f'(让平:{rangqiu_draw_count}|{rangqiu_draws_percent}%|{rangqiu_draw_payback_percent_str}%) '
                    f'(让负:{rangqiu_lose_count}|{rangqiu_loses_percent}%|{rangqiu_lose_payback_percent_str}%)  (让球赛果:{match.rangqiu_result})\n'
                    f'     赔率：({match.win}|{match.draw}|{match.lose}) 公平赔率:({backtest_results["expect_win_ratio"]}|{backtest_results["expect_draw_ratio"]}|{backtest_results["expect_lose_ratio"]})\n'
                    f'     让球赔率：({match.rangqiu_win}|{match.rangqiu_draw}|{match.rangqiu_lose})'
                    f'公平赔率:({backtest_results["expect_rangqiu_win_ratio"]}|{backtest_results["expect_rangqiu_draw_ratio"]}|{backtest_results["expect_rangqiu_lose_ratio"]})'
                )

            if predict_result == NOT_BETTING and predict_rangqiu_result == NOT_BETTING:
                if (print_log):
                    # print(f"{match.no} 不下注")
                    predict_history.append(f"{match.no} 不下注")
                continue
            else:
                predict_result_str = f'\033[31m{predict_result}\033[0m' if predict_result != NOT_BETTING else predict_result
                predict_rangqiu_result_str = f'\033[31m{predict_rangqiu_result}\033[0m' if predict_rangqiu_result != NOT_BETTING else predict_rangqiu_result
                str = f"{match.no} 胜平负:{predict_result_str if predict_result != NOT_BETTING else '不下注'} 让球胜平负：{predict_rangqiu_result_str if predict_rangqiu_result != NOT_BETTING else '不下注'}"
                # print(str)
                predict_history.append(str)

            predict_result_str = (
                f'{match.no} 胜平负 {"停" if predict_result == NOT_BETTING else f"{predict_result}-{match.result}"} '
                f'让球胜平负 {"停" if predict_rangqiu_result == NOT_BETTING else f"{predict_rangqiu_result}-{match.rangqiu_result}"} '
                f'ev1:{round(match_bonus_amount - match_bet_amount, 2)},{round(match_rangqiu_bonus_amount - match_rangqiu_bet_amount, 2)} '
                f'total_bet:{self.total_bet_amount},{self.total_rangqiu_bet_amount} '
                f'total_wins:{round(self.total_bonus_amount, 2)},{round(self.total_rangqiu_bonus_amount, 2)} '
                f'total_ev1:{round(self.total_bonus_amount - self.total_bet_amount, 2)},{round(self.total_rangqiu_bonus_amount - self.total_rangqiu_bet_amount, 2)}')
            predict_result_history.append(predict_result_str)
            if (print_log):
                print(predict_result_str)

        if (print_log):
            for s in predict_history:
                print(s)

            print("=====Result=====")
            for s in predict_result_history:
                print(s)

        return predicts

    def predict_goal(self, dt="", use_online_data=False, use_online_data_day=0, error_margin=0.05, nice_percent=125,
                     min_same_count=10, print_log=True):
        match_bet_amount = 0
        match_bet_count = 0
        match_bonus_amount = 0
        match_bonus_count = 0
        match_rangqiu_bet_amount = 0
        match_rangqiu_bet_count = 0
        match_rangqiu_bonus_amount = 0
        match_rangqiu_bonus_count = 0

        match_goal_bet_amount = 0
        match_goal_bonus = 0

        predict_history = []
        predict_result_history = []

        predicts = {}

        if use_online_data:
            matches = data_utils.read_matches(use_online_data_day)
        else:
            matches = self.read_matches(dt)
        if (not matches or len(matches) == 0):
            return

        self.total_match_count += len(matches)

        for k in matches.keys():
            match = matches[k]
            predict_goal_results = self.predict_match_goals(match, error_margin,
                                                            nice_percent,
                                                            min_same_count)
            if predict_goal_results:
                predict_goal = predict_goal_results["predict_goal"]
                goal_nums = []
                for item in predict_goal:
                    goal = item[0]
                    payback = item[1]
                    goal_nums.append(goal)
                    self.total_goal_bet_amount += 1
                    self.total_goal_bet_count += 1
                    if (goal == match.goal_result):
                        self.total_goal_bonus_count += 1
                        if (goal == 0):
                            match_goal_bonus = match.goal_0
                            self.total_goal_bonus_amount += match_goal_bonus

                        if (goal == 1):
                            match_goal_bonus = match.goal_1
                            self.total_goal_bonus_amount += match_goal_bonus

                        if (goal == 2):
                            match_goal_bonus = match.goal_2
                            self.total_goal_bonus_amount += match_goal_bonus

                        if (goal == 3):
                            match_goal_bonus = match.goal_3
                            self.total_goal_bonus_amount += match_goal_bonus

                        if (goal == 4):
                            match_goal_bonus = match.goal_4
                            self.total_goal_bonus_amount += match_goal_bonus

                        if (goal == 5):
                            match_goal_bonus = match.goal_5
                            self.total_goal_bonus_amount += match_goal_bonus

                        if (goal == 6):
                            match_goal_bonus = match.goal_6
                            self.total_goal_bonus_amount += match_goal_bonus

                        if (goal == 7):
                            match_goal_bonus = match.goal_7
                            self.total_goal_bonus_amount += match_goal_bonus

                print(
                    f"{match.no} 预:{goal_nums} 开:{match.goal_result} 赔:{match_goal_bonus} 赢:{round(match_goal_bonus - len(predict_goal), 2)} 总下:{self.total_goal_bet_amount} "
                    f"总奖:{round(self.total_goal_bonus_amount, 2)} 总中:{self.total_goal_bonus_count} 总赢:{round(self.total_goal_bonus_amount - self.total_goal_bet_amount, 2)}")
            else:
                # print("无符合场次，不下注进球数")
                pass

        return predicts

    def ev_predict_match(self, match, error_margin=0.05, nice_percent=120, min_same_count=20):
        options = {"use_league": False,
                   "use_win": True,
                   "use_draw": True,
                   "use_lose": True,
                   "use_rangqiu_num": True,
                   "use_rangqiu_win": True,
                   "use_rangqiu_draw": True,
                   "use_rangqiu_lose": True,
                   "margin_of_error": error_margin,
                   "nice_percent": nice_percent}
        options = self.prepare_options(match, options)
        history_matches = self.query_matches(options)
        if (len(history_matches) == 0):
            return NOT_BETTING, NOT_BETTING, None

        results = self.backtest(match, history_matches)
        nice_percent = options["nice_percent"]
        predict_result = NOT_BETTING
        rangqiu_predict_result = NOT_BETTING

        expect_win_ratio = round(100 / results['wins_percent'], 2) if results['wins_percent'] > 0 else VERY_BIG_RATIO
        expect_draw_ratio = round(100 / results['draws_percent'], 2) if results['draws_percent'] > 0 else VERY_BIG_RATIO
        expect_lose_ratio = round(100 / results['losses_percent'], 2) if results[
                                                                             'losses_percent'] > 0 else VERY_BIG_RATIO
        expect_rangqiu_win_ratio = round(100 / results['rangqiu_wins_percent'], 2) if results[
                                                                                          'rangqiu_wins_percent'] > 0 else VERY_BIG_RATIO
        expect_rangqiu_draw_ratio = round(100 / results['rangqiu_draws_percent'], 2) if results[
                                                                                            'rangqiu_draws_percent'] > 0 else VERY_BIG_RATIO
        expect_rangqiu_lose_ratio = round(100 / results['rangqiu_loses_percent'], 2) if results[
                                                                                            'rangqiu_loses_percent'] > 0 else VERY_BIG_RATIO

        win_ratio_profit = float(match.win) - expect_win_ratio
        draw_ratio_profit = float(match.draw) - expect_draw_ratio
        lose_ratio_profit = float(match.lose) - expect_lose_ratio
        rangqiu_win_ratio_profit = float(match.rangqiu_win) - expect_rangqiu_win_ratio
        rangqiu_draw_ratio_profit = float(match.rangqiu_draw) - expect_rangqiu_draw_ratio
        rangqiu_lose_ratio_profit = float(match.rangqiu_lose) - expect_rangqiu_lose_ratio

        # 胜
        if win_ratio_profit > draw_ratio_profit and win_ratio_profit > lose_ratio_profit:
            if win_ratio_profit > 0 and 100 * float(match.win) / expect_win_ratio > nice_percent:
                predict_result = 3

        # 平
        if draw_ratio_profit > win_ratio_profit and draw_ratio_profit > lose_ratio_profit:
            if draw_ratio_profit > 0 and 100 * float(match.draw) / expect_draw_ratio > nice_percent:
                predict_result = 1

        # 负
        if lose_ratio_profit > draw_ratio_profit and lose_ratio_profit > win_ratio_profit:
            if lose_ratio_profit > 0 and 100 * float(match.lose) / expect_lose_ratio > nice_percent:
                predict_result = 0

        # 让胜
        if rangqiu_win_ratio_profit > rangqiu_draw_ratio_profit and rangqiu_win_ratio_profit > rangqiu_lose_ratio_profit:
            if rangqiu_win_ratio_profit > 0 and 100 * float(
                    match.rangqiu_win) / expect_rangqiu_win_ratio > nice_percent:
                rangqiu_predict_result = 3

        # 让平
        if rangqiu_draw_ratio_profit > rangqiu_win_ratio_profit and rangqiu_draw_ratio_profit > rangqiu_lose_ratio_profit:
            if rangqiu_draw_ratio_profit > 0 and 100 * float(
                    match.rangqiu_draw) / expect_rangqiu_draw_ratio > nice_percent:
                rangqiu_predict_result = 1

        # 让负
        if rangqiu_lose_ratio_profit > rangqiu_win_ratio_profit and rangqiu_lose_ratio_profit > rangqiu_draw_ratio_profit:
            if rangqiu_lose_ratio_profit > 0 and 100 * float(
                    match.rangqiu_lose) / expect_rangqiu_lose_ratio > nice_percent:
                rangqiu_predict_result = 0

        if (len(history_matches) < min_same_count):
            predict_result = NOT_BETTING
            rangqiu_predict_result = NOT_BETTING

        results["expect_win_ratio"] = expect_win_ratio
        results["expect_draw_ratio"] = expect_draw_ratio
        results["expect_lose_ratio"] = expect_lose_ratio
        results["expect_rangqiu_win_ratio"] = expect_rangqiu_win_ratio
        results["expect_rangqiu_draw_ratio"] = expect_rangqiu_draw_ratio
        results["expect_rangqiu_lose_ratio"] = expect_rangqiu_lose_ratio

        return predict_result, rangqiu_predict_result, results

    def ev_predict(self, dt="", use_online_data=False, use_online_data_day=0, error_margin=0.05, nice_percent=125,
                   min_same_count=10, print_log=True):
        match_bet_amount = 0
        match_bet_count = 0
        match_bonus_amount = 0
        match_bonus_count = 0
        match_rangqiu_bet_amount = 0
        match_rangqiu_bet_count = 0
        match_rangqiu_bonus_amount = 0
        match_rangqiu_bonus_count = 0
        predict_history = []
        predict_result_history = []

        predicts = {}

        if use_online_data:
            matches = data_utils.read_matches(use_online_data_day)
        else:
            matches = self.read_matches(dt)
        if (not matches or len(matches) == 0):
            return

        self.total_match_count += len(matches)

        for k in matches.keys():
            match = matches[k]
            predict_result, predict_rangqiu_result, backtest_results = self.ev_predict_match(match, error_margin,
                                                                                             nice_percent,
                                                                                             min_same_count)

            predicts[match.game_date + " " + match.no] = [predict_result, predict_rangqiu_result]

            if predict_result == NOT_BETTING and predict_rangqiu_result == predict_result and not backtest_results:
                if (print_log):
                    # print(f"{match.no} 不下注")
                    predict_history.append(f"{match.no} 不下注")
                continue

            if predict_result != NOT_BETTING:
                match_bet_amount = 1
                match_bet_count = 1
                match_bonus_amount = 0
                match_bonus_count = 0
                if (predict_result == int(match.result)):
                    match_bonus_count = 1
                    if (predict_result == 0):
                        match_bonus_amount = float(match.lose)
                    if (predict_result == 1):
                        match_bonus_amount = float(match.draw)
                    if (predict_result == 3):
                        match_bonus_amount = float(match.win)
                self.total_bet_amount += match_bet_amount
                self.total_bet_count += match_bet_count
                self.total_bonus_amount += match_bonus_amount
                self.total_bonus_count += match_bonus_count

            if predict_rangqiu_result != NOT_BETTING:
                match_rangqiu_bet_amount = 1
                match_rangqiu_bet_count = 1
                match_rangqiu_bonus_amount = 0
                match_rangqiu_bonus_count = 0
                if (predict_rangqiu_result == int(match.rangqiu_result)):
                    match_rangqiu_bonus_count = 1
                    if (predict_rangqiu_result == 0):
                        match_rangqiu_bonus_amount = float(match.rangqiu_lose)
                    if (predict_rangqiu_result == 1):
                        match_rangqiu_bonus_amount = float(match.rangqiu_draw)
                    if (predict_rangqiu_result == 3):
                        match_rangqiu_bonus_amount = float(match.rangqiu_win)
                self.total_rangqiu_bet_amount += match_rangqiu_bet_amount
                self.total_rangqiu_bet_count += match_rangqiu_bet_count
                self.total_rangqiu_bonus_amount += match_rangqiu_bonus_amount
                self.total_rangqiu_bonus_count += match_rangqiu_bonus_count

            match_no = f'\033[31m{match.no}\033[0m'
            same_count = backtest_results["same_count"]

            win_count = backtest_results["win_count"]
            draw_count = backtest_results["draw_count"]
            lose_count = backtest_results["lose_count"]

            wins_percent = backtest_results["wins_percent"]
            draws_percent = backtest_results["draws_percent"]
            losses_percent = backtest_results["losses_percent"]

            rangqiu_win_count = backtest_results["rangqiu_win_count"]
            rangqiu_draw_count = backtest_results["rangqiu_draw_count"]
            rangqiu_lose_count = backtest_results["rangqiu_lose_count"]

            rangqiu_wins_percent = backtest_results["rangqiu_wins_percent"]
            rangqiu_draws_percent = backtest_results["rangqiu_draws_percent"]
            rangqiu_loses_percent = backtest_results["rangqiu_loses_percent"]

            same_count = f'\033[31m{same_count}\033[0m' if same_count > min_same_count else same_count
            if (print_log):
                print(
                    f'{match_no} {match.game_date} {match.league} {"{:<5}".format(match.home_team)} vs {"{:>5}".format(match.away_team)} '
                    f'让球:{match.rangqiu}\n'
                    f'    历史同赔: {same_count} '
                    f'  (胜:{win_count}|{wins_percent}%|%) '
                    f'(平:{draw_count}|{draws_percent}%|%) '
                    f'(负:{lose_count}|{losses_percent}%|%)  (赛果:{match.result})       '
                    f'(让胜:{rangqiu_win_count}|{rangqiu_wins_percent}%|%) '
                    f'(让平:{rangqiu_draw_count}|{rangqiu_draws_percent}%|%) '
                    f'(让负:{rangqiu_lose_count}|{rangqiu_loses_percent}%|%)  (让球赛果:{match.rangqiu_result})\n'
                    f'     赔率：({match.win}|{match.draw}|{match.lose}) 公平赔率:({backtest_results["expect_win_ratio"]}|{backtest_results["expect_draw_ratio"]}|{backtest_results["expect_lose_ratio"]})\n'
                    f'     让球赔率：({match.rangqiu_win}|{match.rangqiu_draw}|{match.rangqiu_lose})'
                    f'公平赔率:({backtest_results["expect_rangqiu_win_ratio"]}|{backtest_results["expect_rangqiu_draw_ratio"]}|{backtest_results["expect_rangqiu_lose_ratio"]})'
                )

            if predict_result == NOT_BETTING and predict_rangqiu_result == NOT_BETTING:
                if (print_log):
                    # print(f"{match.no} 不下注")
                    predict_history.append(f"{match.no} 不下注")
                continue
            else:
                predict_result_str = f'\033[31m{predict_result}\033[0m' if predict_result != NOT_BETTING else predict_result
                predict_rangqiu_result_str = f'\033[31m{predict_rangqiu_result}\033[0m' if predict_rangqiu_result != NOT_BETTING else predict_rangqiu_result
                str = f"{match.no} 胜平负:{predict_result_str if predict_result != NOT_BETTING else '不下注'} 让球胜平负：{predict_rangqiu_result_str if predict_rangqiu_result != NOT_BETTING else '不下注'}"
                # print(str)
                predict_history.append(str)

            predict_result_str = (
                f'{match.no} 胜平负 {"停" if predict_result == NOT_BETTING else f"{predict_result}-{match.result}"} '
                f'让球胜平负 {"停" if predict_rangqiu_result == NOT_BETTING else f"{predict_rangqiu_result}-{match.rangqiu_result}"} '
                f'ev1:{round(match_bonus_amount - match_bet_amount, 2)},{round(match_rangqiu_bonus_amount - match_rangqiu_bet_amount, 2)} '
                f'total_bet:{self.total_bet_amount},{self.total_rangqiu_bet_amount} '
                f'total_wins:{round(self.total_bonus_amount, 2)},{round(self.total_rangqiu_bonus_amount, 2)} '
                f'total_ev1:{round(self.total_bonus_amount - self.total_bet_amount, 2)},{round(self.total_rangqiu_bonus_amount - self.total_rangqiu_bet_amount, 2)}')
            predict_result_history.append(predict_result_str)
            if (print_log):
                print(predict_result_str)

        if (print_log):
            for s in predict_history:
                print(s)

            print("=====Result=====")
            for s in predict_result_history:
                print(s)

        return predicts

    def backtest(self, match, df):
        if (len(df) == 0):
            # print(f'{match.no} 暂无符合场次')
            return

        total = 0
        win_amount = 0
        win_count = 0
        lose_amount = 0
        lose_count = 0
        draw_amount = 0
        draw_count = 0

        rangqiu_win_amount = 0
        rangqiu_win_count = 0
        rangqiu_draw_amount = 0
        rangqiu_draw_count = 0
        rangqiu_lose_amount = 0
        rangqiu_lose_count = 0

        goal_0_count = 0
        goal_1_count = 0
        goal_2_count = 0
        goal_3_count = 0
        goal_4_count = 0
        goal_5_count = 0
        goal_6_count = 0
        goal_7_count = 0

        goal_0_amount = 0
        goal_1_amount = 0
        goal_2_amount = 0
        goal_3_amount = 0
        goal_4_amount = 0
        goal_5_amount = 0
        goal_6_amount = 0
        goal_7_amount = 0

        for row in df.itertuples():
            total += 1
            if row.赛果 == "胜":
                win_amount += row.胜临
                # win_amount += float(match.win)
                win_count += 1

            if row.赛果 == "平":
                draw_amount += row.平临
                # draw_amount += float(match.draw)
                draw_count += 1

            if row.赛果 == "负":
                lose_amount += row.负临
                # lose_amount += float(match.lose)
                lose_count += 1

            if row.让球赛果 == "胜":
                rangqiu_win_amount += row.让胜临
                # rangqiu_win_amount += float(match.rangqiu_win)
                rangqiu_win_count += 1

            if row.让球赛果 == "平":
                rangqiu_draw_amount += row.让平临
                # rangqiu_draw_amount += float(match.rangqiu_draw)
                rangqiu_draw_count += 1

            if row.让球赛果 == "负":
                rangqiu_lose_amount += row.让负临
                # rangqiu_lose_amount += float(match.rangqiu_lose)
                rangqiu_lose_count += 1

            if row.总进球 == 0:
                goal_0_count += 1
                goal_0_amount += row.总进球赔率

            if row.总进球 == 1:
                goal_1_count += 1
                goal_1_amount += row.总进球赔率

            if row.总进球 == 2:
                goal_2_count += 1
                goal_2_amount += row.总进球赔率

            if row.总进球 == 3:
                goal_3_count += 1
                goal_3_amount += row.总进球赔率

            if row.总进球 == 4:
                goal_4_count += 1
                goal_4_amount += row.总进球赔率

            if row.总进球 == 5:
                goal_5_count += 1
                goal_5_amount += row.总进球赔率

            if row.总进球 == 6:
                goal_6_count += 1
                goal_6_amount += row.总进球赔率

            if row.总进球 == 7:
                goal_7_count += 1
                goal_7_amount += row.总进球赔率

        win_payback_percent = round(100 * float(match.win) * win_count / total)
        wins_percent = round(100 * win_count / total)
        draw_payback_percent = round(100 * float(match.draw) * draw_count / total)
        draws_percent = round(100 * draw_count / total)
        lose_payback_percent = round(100 * float(match.lose) * lose_count / total)
        losses_percent = round(100 * lose_count / total)

        rangqiu_win_payback_percent = round(100 * rangqiu_win_amount / total)
        rangqiu_wins_percent = round(100 * rangqiu_win_count / total)
        rangqiu_draw_payback_percent = round(100 * rangqiu_draw_amount / total)
        rangqiu_draws_percent = round(100 * rangqiu_draw_count / total)
        rangqiu_lose_payback_percent = round(100 * rangqiu_lose_amount / total)
        rangqiu_loses_percent = round(100 * rangqiu_lose_count / total)

        goal_0_payback_percent = round(100 * goal_0_amount / total)
        goal_1_payback_percent = round(100 * goal_1_amount / total)
        goal_2_payback_percent = round(100 * goal_2_amount / total)
        goal_3_payback_percent = round(100 * goal_3_amount / total)
        goal_4_payback_percent = round(100 * goal_4_amount / total)
        goal_5_payback_percent = round(100 * goal_5_amount / total)
        goal_6_payback_percent = round(100 * goal_6_amount / total)
        goal_7_payback_percent = round(100 * goal_7_amount / total)

        goal_0_avg = round(goal_0_amount / goal_0_count, 2) if goal_0_count > 0 else 0
        goal_1_avg = round(goal_1_amount / goal_1_count, 2) if goal_1_count > 0 else 0
        goal_2_avg = round(goal_2_amount / goal_2_count, 2) if goal_2_count > 0 else 0
        goal_3_avg = round(goal_3_amount / goal_3_count, 2) if goal_3_count > 0 else 0
        goal_4_avg = round(goal_4_amount / goal_4_count, 2) if goal_4_count > 0 else 0
        goal_5_avg = round(goal_5_amount / goal_5_count, 2) if goal_5_count > 0 else 0
        goal_6_avg = round(goal_6_amount / goal_6_count, 2) if goal_6_count > 0 else 0
        goal_7_avg = round(goal_7_amount / goal_7_count, 2) if goal_7_count > 0 else 0

        test_result = {
            "same_count": len(df),
            "win_count": win_count,
            "draw_count": draw_count,
            "lose_count": lose_count,
            "wins_percent": wins_percent,
            "draws_percent": draws_percent,
            "losses_percent": losses_percent,
            "win_payback_percent": win_payback_percent,
            "draw_payback_percent": draw_payback_percent,
            "lose_payback_percent": lose_payback_percent,
            "rangqiu_win_count": rangqiu_win_count,
            "rangqiu_draw_count": rangqiu_draw_count,
            "rangqiu_lose_count": rangqiu_lose_count,
            "rangqiu_wins_percent": rangqiu_wins_percent,
            "rangqiu_draws_percent": rangqiu_draws_percent,
            "rangqiu_loses_percent": rangqiu_loses_percent,
            "rangqiu_win_payback_percent": rangqiu_win_payback_percent,
            "rangqiu_draw_payback_percent": rangqiu_draw_payback_percent,
            "rangqiu_lose_payback_percent": rangqiu_lose_payback_percent,
            "goal_0_payback_percent": goal_0_payback_percent,
            "goal_1_payback_percent": goal_1_payback_percent,
            "goal_2_payback_percent": goal_2_payback_percent,
            "goal_3_payback_percent": goal_3_payback_percent,
            "goal_4_payback_percent": goal_4_payback_percent,
            "goal_5_payback_percent": goal_5_payback_percent,
            "goal_6_payback_percent": goal_6_payback_percent,
            "goal_7_payback_percent": goal_7_payback_percent,
            "goal_0_avg": goal_0_avg,
            "goal_1_avg": goal_1_avg,
            "goal_2_avg": goal_2_avg,
            "goal_3_avg": goal_3_avg,
            "goal_4_avg": goal_4_avg,
            "goal_5_avg": goal_5_avg,
            "goal_6_avg": goal_6_avg,
            "goal_7_avg": goal_7_avg,
            "goal_0_count": goal_0_count,
            "goal_1_count": goal_1_count,
            "goal_2_count": goal_2_count,
            "goal_3_count": goal_3_count,
            "goal_4_count": goal_4_count,
            "goal_5_count": goal_5_count,
            "goal_6_count": goal_6_count,
            "goal_7_count": goal_7_count
        }
        return test_result

    def predict_match(self, match, error_margin=0.05, nice_percent=120, min_same_count=20):
        options = {"use_league": False,
                   "use_win": True,
                   "use_draw": True,
                   "use_lose": True,
                   "use_rangqiu_num": True,
                   "use_rangqiu_win": True,
                   "use_rangqiu_draw": True,
                   "use_rangqiu_lose": True,
                   "margin_of_error": error_margin,
                   "nice_percent": nice_percent}
        options = self.prepare_options(match, options)
        history_matches = self.query_matches(options)
        if (len(history_matches) == 0):
            return NOT_BETTING, NOT_BETTING, None

        results = self.backtest(match, history_matches)
        win_payback_percent = results["win_payback_percent"]
        draw_payback_percent = results["draw_payback_percent"]
        lose_payback_percent = results["lose_payback_percent"]

        rangqiu_win_payback_percent = results["rangqiu_win_payback_percent"]
        rangqiu_draw_payback_percent = results["rangqiu_draw_payback_percent"]
        rangqiu_lose_payback_percent = results["rangqiu_lose_payback_percent"]

        nice_percent = options["nice_percent"]
        predict_result = NOT_BETTING
        rangqiu_predict_result = NOT_BETTING

        ev_win = results["win_count"] * (win_payback_percent - 100)
        ev_draw = results["draw_count"] * (draw_payback_percent - 100)
        ev_lose = results["lose_count"] * (lose_payback_percent - 100)

        ev_rangqiu_win = results["rangqiu_win_count"] * (rangqiu_win_payback_percent - 100)
        ev_rangqiu_draw = results["rangqiu_draw_count"] * (rangqiu_draw_payback_percent - 100)
        ev_rangqiu_lose = results["rangqiu_lose_count"] * (rangqiu_lose_payback_percent - 100)

        # if (ev_win > ev_draw and ev_win > ev_lose):
        #     if win_payback_percent > nice_percent:
        #         predict_result = 3
        #
        # if (ev_draw > ev_win and ev_draw > ev_lose):
        #     if draw_payback_percent > nice_percent:
        #         predict_result = 1
        #
        # if (ev_lose > ev_win and ev_lose > ev_draw):
        #     if lose_payback_percent > nice_percent:
        #         predict_result = 0
        #
        # if (
        #         ev_rangqiu_win > ev_rangqiu_draw and ev_rangqiu_win > ev_rangqiu_lose):
        #     if rangqiu_win_payback_percent > nice_percent:
        #         rangqiu_predict_result = 3
        #
        # if (
        #         ev_rangqiu_draw > ev_rangqiu_win and ev_rangqiu_draw > ev_rangqiu_lose):
        #     if rangqiu_draw_payback_percent > nice_percent:
        #         rangqiu_predict_result = 1
        #
        # if (
        #         ev_rangqiu_lose > ev_rangqiu_win and ev_rangqiu_lose > ev_rangqiu_draw):
        #     if rangqiu_lose_payback_percent > nice_percent:
        #         rangqiu_predict_result = 0

        if (win_payback_percent >= draw_payback_percent and win_payback_percent >= lose_payback_percent):
            if win_payback_percent >= nice_percent:
                predict_result = 3

        if (draw_payback_percent >= win_payback_percent and draw_payback_percent >= lose_payback_percent):
            if draw_payback_percent >= nice_percent:
                predict_result = 1

        if (lose_payback_percent >= win_payback_percent and lose_payback_percent >= draw_payback_percent):
            if lose_payback_percent >= nice_percent:
                predict_result = 0

        if (
                rangqiu_win_payback_percent >= rangqiu_draw_payback_percent and rangqiu_win_payback_percent >= rangqiu_lose_payback_percent):
            if rangqiu_win_payback_percent >= nice_percent:
                rangqiu_predict_result = 3

        if (
                rangqiu_draw_payback_percent >= rangqiu_win_payback_percent and rangqiu_draw_payback_percent >= rangqiu_lose_payback_percent):
            if rangqiu_draw_payback_percent >= nice_percent:
                rangqiu_predict_result = 1

        if (
                rangqiu_lose_payback_percent >= rangqiu_win_payback_percent and rangqiu_lose_payback_percent >= rangqiu_draw_payback_percent):
            if rangqiu_lose_payback_percent >= nice_percent:
                rangqiu_predict_result = 0

        if (not results or results["same_count"] < min_same_count):
            predict_result = NOT_BETTING
            rangqiu_predict_result = NOT_BETTING

        expect_win_ratio = round(100 / results['wins_percent'], 2) if results['wins_percent'] > 0 else 999
        expect_draw_ratio = round(100 / results['draws_percent'], 2) if results['draws_percent'] > 0 else 999
        expect_lose_ratio = round(100 / results['losses_percent'], 2) if results['losses_percent'] > 0 else 999
        expect_rangqiu_win_ratio = round(100 / results['rangqiu_wins_percent'], 2) if results[
                                                                                          'rangqiu_wins_percent'] > 0 else 999
        expect_rangqiu_draw_ratio = round(100 / results['rangqiu_draws_percent'], 2) if results[
                                                                                            'rangqiu_draws_percent'] > 0 else 999
        expect_rangqiu_lose_ratio = round(100 / results['rangqiu_loses_percent'], 2) if results[
                                                                                            'rangqiu_loses_percent'] > 0 else 999

        results["expect_win_ratio"] = expect_win_ratio
        results["expect_draw_ratio"] = expect_draw_ratio
        results["expect_lose_ratio"] = expect_lose_ratio
        results["expect_rangqiu_win_ratio"] = expect_rangqiu_win_ratio
        results["expect_rangqiu_draw_ratio"] = expect_rangqiu_draw_ratio
        results["expect_rangqiu_lose_ratio"] = expect_rangqiu_lose_ratio

        return predict_result, rangqiu_predict_result, results

    def predict_match_goals(self, match, error_margin, nice_percent, min_same_count):
        options = {"use_league": True,
                   "use_win": False,
                   "use_draw": False,
                   "use_lose": False,
                   "use_rangqiu_num": False,
                   "use_rangqiu_win": False,
                   "use_rangqiu_draw": False,
                   "use_rangqiu_lose": False,
                   "use_goal_0": False,
                   "use_goal_1": True,
                   "use_goal_2": False,
                   "use_goal_3": False,
                   "use_goal_4": False,
                   "use_goal_5": False,
                   "use_goal_6": False,
                   "use_goal_7": False,
                   "margin_of_error": error_margin,
                   "nice_percent": nice_percent}
        options = self.prepare_goal_options(match, options)
        history_matches = self.query_matches(options)
        if (len(history_matches) < min_same_count):
            return None

        results = self.backtest(match, history_matches)
        predict_goal = []
        if (results["goal_0_payback_percent"] >= nice_percent):
            predict_goal.append({0: 0, 1: results["goal_0_payback_percent"], 2: results["goal_0_count"]})

        if (results["goal_1_payback_percent"] >= nice_percent):
            predict_goal.append({0: 1, 1: results["goal_1_payback_percent"], 2: results["goal_1_count"]})

        if (results["goal_2_payback_percent"] >= nice_percent):
            predict_goal.append({0: 2, 1: results["goal_2_payback_percent"], 2: results["goal_2_count"]})

        if (results["goal_3_payback_percent"] >= nice_percent):
            predict_goal.append({0: 3, 1: results["goal_3_payback_percent"], 2: results["goal_3_count"]})

        if (results["goal_4_payback_percent"] >= nice_percent):
            predict_goal.append({0: 4, 1: results["goal_4_payback_percent"], 2: results["goal_4_count"]})

        if (results["goal_5_payback_percent"] >= nice_percent):
            predict_goal.append({0: 5, 1: results["goal_5_payback_percent"], 2: results["goal_5_count"]})

        if (results["goal_6_payback_percent"] >= nice_percent):
            predict_goal.append({0: 6, 1: results["goal_6_payback_percent"], 2: results["goal_6_count"]})

        if (results["goal_7_payback_percent"] >= nice_percent):
            predict_goal.append({0: 7, 1: results["goal_7_payback_percent"], 2: results["goal_7_count"]})

        predict_goal = sorted(predict_goal, key=lambda x: -x[2])
        results["predict_goal"] = predict_goal[:1]
        return results

    def backtest_period(self, start_date, period, strategy):
        self.init_data()
        for i in range(0, -period, -1):
            d = datetime.strptime(start_date, "%Y-%m-%d")
            current_date = (d + timedelta(days=i)).strftime("%Y-%m-%d")
            self.ev_predict(dt=current_date, error_margin=strategy["error_margin"],
                            nice_percent=strategy["nice_percent"],
                            min_same_count=strategy["min_same_count"], print_log=False)

        result = {
            "start_date": start_date,
            "period": period,
            "total_bet_amount": self.total_bet_amount,
            "total_rangqiu_bet_amount": self.total_rangqiu_bet_amount,
            "total_bonus_amount": round(self.total_bonus_amount, 2),
            "total_rangqiu_bonus_amount": round(self.total_rangqiu_bonus_amount, 2),
            "ev": round(self.total_bonus_amount - self.total_bet_amount, 2),
            "rangqiu_ev": round(self.total_rangqiu_bonus_amount - self.total_rangqiu_bet_amount, 2),
        }
        return result

    def predict_day(self, day=0, print_log=False, strategy=None):
        predicts = self.predict(use_online_data_day=day, use_online_data=True, error_margin=strategy.error_margin,
                                nice_percent=strategy.nice_percent,
                                min_same_count=strategy.min_same_count,
                                print_log=print_log)
        predict_str = (f"{strategy.name} e:{str(strategy.error_margin)} "
                       f"n:{strategy.nice_percent} "
                       f"s:{strategy.min_same_count} "
                       f"c:{self.total_match_count} "
                       f"B:({self.total_bet_amount},{self.total_rangqiu_bet_amount}) W:({round(self.total_bonus_amount, 0)},{round(self.total_rangqiu_bonus_amount, 0)}) "
                       f"E:({round(self.total_bonus_amount - self.total_bet_amount, 0)},{round(self.total_rangqiu_bonus_amount - self.total_rangqiu_bet_amount, 0)})"
                       ).ljust(70, " ")

        result_map = {0: "0", 1: "1", 3: "3", 99: "-"}
        # for k ,v in result_map.items():
        #     if v != "-":
        #         result_map[k] = f'\033[31m{v}\033[0m'

        rangqiu_result_map = {0: "00", 1: "11", 3: "33", 99: "-"}
        # for k ,v in rangqiu_result_map.items():
        #     if v != "-":
        #         rangqiu_result_map[k] = f'\033[31m{v}\033[0m'

        predict_str += '\n    胜负 '
        for k in predicts.keys():
            kk = k.split(" ")[1]
            if (predicts[k][0] == NOT_BETTING):
                continue
            predict_str += f"({kk} {str(result_map[predicts[k][0]]).rjust(3, ' ')})"

        predict_str += '\n    让球 '
        for k in predicts.keys():
            kk = k.split(" ")[1]
            if (predicts[k][1] == NOT_BETTING):
                continue
            predict_str += f"({kk} {str(rangqiu_result_map[predicts[k][1]]).ljust(3, ' ')})"

        print(predict_str)
        self.last_predict_str = predict_str

    def ev_predict_day(self, day=0, print_log=False, strategy=None):
        predicts = self.ev_predict(use_online_data_day=day, use_online_data=True, error_margin=strategy["error_margin"],
                                   nice_percent=strategy["nice_percent"],
                                   min_same_count=strategy["min_same_count"],
                                   print_log=print_log)
        predict_str = (f"{strategy['name']} e:{str(strategy['error_margin'])} "
                       f"n:{strategy['nice_percent']} "
                       f"s:{strategy['min_same_count']} "
                       f"c:{self.total_match_count} "
                       f"B:({self.total_bet_amount},{self.total_rangqiu_bet_amount}) W:({round(self.total_bonus_amount, 2)},{round(self.total_rangqiu_bonus_amount, 2)}) "
                       f"E:({round(self.total_bonus_amount - self.total_bet_amount, 2)},{round(self.total_rangqiu_bonus_amount - self.total_rangqiu_bet_amount, 2)})"
                       ).ljust(70, " ")
        result_map = {0: "0", 1: "1", 3: "3", 99: "-"}
        # for k ,v in result_map.items():
        #     if v != "-":
        #         result_map[k] = f'\033[31m{v}\033[0m'

        rangqiu_result_map = {0: "00", 1: "11", 3: "33", 99: "-"}
        # for k ,v in rangqiu_result_map.items():
        #     if v != "-":
        #         rangqiu_result_map[k] = f'\033[31m{v}\033[0m'

        predict_str += '\n    胜负 '
        for k in predicts.keys():
            kk = k.split(" ")[1]
            if (predicts[k][0] == NOT_BETTING):
                continue
            predict_str += f"({kk} {str(result_map[predicts[k][0]]).rjust(3, ' ')})"

        predict_str += '\n    让球 '
        for k in predicts.keys():
            kk = k.split(" ")[1]
            if (predicts[k][1] == NOT_BETTING):
                continue
            predict_str += f"({kk} {str(rangqiu_result_map[predicts[k][1]]).ljust(3, ' ')})"

        print(predict_str)
        self.last_predict_str = predict_str


def read_test_data(start_date, end_date):
    df = pd.read_csv(DATA_FILE, encoding="UTF-8",
                     usecols=["场次", "比赛时间", "联赛", "主客场", "赛果", "让球赛果", "胜临", "平临",
                              "负临", "让胜临", "让平临", "让负临", "让球", "总进球",
                              "0临", "1临", "2临", "3临", "4临", "5临", "6临", "7临",
                              "0", "1", "2", "3", "4", "5", "6", "7",
                              "总进球赔率", "半全场",
                              "胜胜", "胜平", "胜负",
                              "平胜", "平平", "平负",
                              "负胜", "负平", "负负",
                              "胜胜临", "胜平临", "胜负临",
                              "平胜临", "平平临", "平负临",
                              "负胜临", "负平临", "负负临",
                              ],
                     header=0,
                     low_memory=False
                     )
    df = df.dropna()
    df['比赛时间'] = pd.to_datetime(df['比赛时间'])
    # df.dropna(subset=['半全场','赛果','让球赛果'])
    # df.dropna(axis=0, inplace=True)

    # df = df[(df['比赛时间'] >= "2024-01-01") & ((df['比赛时间'] <= "2024-09-22"))]
    df = df[(df['比赛时间'] >= start_date) & ((df['比赛时间'] <= end_date))]
    df['赛果'] = df['赛果'].apply(lambda x: 3 if x == "胜" else x)
    df['赛果'] = df['赛果'].apply(lambda x: 1 if x == "平" else x)
    df['赛果'] = df['赛果'].apply(lambda x: 0 if x == "负" else x)
    df['让球赛果'] = df['让球赛果'].apply(lambda x: 3 if x == "胜" else x)
    df['让球赛果'] = df['让球赛果'].apply(lambda x: 1 if x == "平" else x)
    df['让球赛果'] = df['让球赛果'].apply(lambda x: 0 if x == "负" else x)
    df['让球赛果'] = df['让球赛果'].apply(lambda x: 3 if x == "让胜" else x)
    df['让球赛果'] = df['让球赛果'].apply(lambda x: 1 if x == "让平" else x)
    df['让球赛果'] = df['让球赛果'].apply(lambda x: 0 if x == "让负" else x)

    matches = []
    for index, row in df.iterrows():
        match = Match()
        match.no = row['场次']
        match.league = row['联赛']
        match.home_team = row['主客场'].split("VS")[0]
        match.away_team = row['主客场'].split("VS")[1]
        match.rangqiu = int(row['让球'])
        match.win = float(row['胜临'])
        match.draw = float(row['平临'])
        match.lose = float(row['负临'])
        match.rangqiu_win = float(row['让胜临'])
        match.rangqiu_draw = float(row['让平临'])
        match.rangqiu_lose = float(row['让负临'])
        match.result = int(row['赛果'])
        match.rangqiu_result = int(row['让球赛果'])
        match.goal_0 = int(row['0'])
        match.goal_1 = int(row['1'])
        match.goal_2 = int(row['2'])
        match.goal_3 = int(row['3'])
        match.goal_4 = int(row['4'])
        match.goal_5 = int(row['5'])
        match.goal_6 = int(row['6'])
        match.goal_7 = int(row['7'])
        match.goal_result = int(row['总进球'])
        match.goal_ratio = float(row['总进球赔率'])

        match.ww = float(row['胜胜临'])
        match.wd = float(row['胜平临'])
        match.wl = float(row['胜负临'])
        match.dw = float(row['平胜临'])
        match.dd = float(row['平平临'])
        match.dl = float(row['平负临'])
        match.lw = float(row['负胜临'])
        match.ld = float(row['负平临'])
        match.ll = float(row['负负临'])

        match.half_result = row['半全场']
        match.game_date = row['比赛时间']
        match.index = index
        matches.append(match)
    return matches


week_day = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]


def backtest_half2(bet_option, type, print_log):
    total_bet = 0
    total_win_amount = 0
    total_win_count = 0
    profit = 0
    gap_days = 0
    max_gap_days = 0
    matches = read_test_data("2024-01-01", "2024-09-22")
    # day_in_week = 0  # 周一
    # day_in_week_str = week_day[day_in_week]
    day_in_week_str = matches[0].no[:2]
    day_in_week = {"周一": 0, "周二": 1, "周三": 2, "周四": 3, "周五": 4, "周六": 5, "周日": 6}[day_in_week_str]

    current_day_match_list = []
    month_record = {}
    for m in matches:
        if (m.no.startswith(day_in_week_str)):
            current_day_match_list.append(m)
        else:

            (max_ww_matches, min_ww_matches,
             max_wd_matches, min_wd_matches,
             max_wl_matches, min_wl_matches,
             max_dw_matches, min_dw_matches,
             max_dd_matches, min_dd_matches,
             max_dl_matches, min_dl_matches,
             max_lw_matches, min_lw_matches,
             max_ld_matches, min_ld_matches,
             max_ll_matches, min_ll_matches,
             max_goal_0_matches, min_goal_0_matches,
             max_goal_1_matches, min_goal_1_matches,
             max_goal_2_matches, min_goal_2_matches,
             max_goal_3_matches, min_goal_3_matches,
             max_goal_4_matches, min_goal_4_matches,
             max_goal_5_matches, min_goal_5_matches,
             max_goal_6_matches, min_goal_6_matches,
             max_goal_7_matches, min_goal_7_matches) = pick_matches(
                current_day_match_list)

            if bet_option == "胜胜" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_ww_matches, "胜胜", print_log)
            elif bet_option == "胜胜" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_ww_matches, "胜胜", print_log)

            elif bet_option == "胜平" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_wd_matches, "胜平", print_log)
            elif bet_option == "胜平" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_wd_matches, "胜平", print_log)

            elif bet_option == "胜负" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_wl_matches, "胜负", print_log)
            elif bet_option == "胜负" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_wl_matches, "胜负", print_log)

            elif bet_option == "平胜" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_dw_matches, "平胜", print_log)
            elif bet_option == "平胜" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_dw_matches, "平胜", print_log)

            elif bet_option == "平平" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_dd_matches, "平平", print_log)
            elif bet_option == "平平" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_dd_matches, "平平", print_log)

            elif bet_option == "平负" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_dl_matches, "平负", print_log)
            elif bet_option == "平负" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_dl_matches, "平负", print_log)

            elif bet_option == "负胜" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_lw_matches, "负胜", print_log)
            elif bet_option == "负胜" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_lw_matches, "负胜", print_log)

            elif bet_option == "负平" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_ld_matches, "负平", print_log)
            elif bet_option == "负平" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_ld_matches, "负平", print_log)

            elif bet_option == "负负" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_ll_matches, "负负", print_log)
            elif bet_option == "负负" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_ll_matches, "负负", print_log)

            elif bet_option == "0球" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_goal_0_matches, "0球", print_log)
            elif bet_option == "0球" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_goal_0_matches, "0球", print_log)

            elif bet_option == "1球" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_goal_1_matches, "1球", print_log)
            elif bet_option == "1球" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_goal_1_matches, "1球", print_log)

            elif bet_option == "2球" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_goal_2_matches, "2球", print_log)
            elif bet_option == "2球" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_goal_2_matches, "2球", print_log)

            elif bet_option == "3球" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_goal_3_matches, "3球", print_log)
            elif bet_option == "3球" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_goal_3_matches, "3球", print_log)

            elif bet_option == "4球" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_goal_4_matches, "4球", print_log)
            elif bet_option == "4球" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_goal_4_matches, "4球", print_log)

            elif bet_option == "5球" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_goal_5_matches, "5球", print_log)
            elif bet_option == "5球" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_goal_5_matches, "5球", print_log)

            elif bet_option == "6球" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_goal_6_matches, "6球", print_log)
            elif bet_option == "6球" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_goal_6_matches, "6球", print_log)

            elif bet_option == "7球" and type == "最大":
                month, bet, win_count, win_amount, profit = back_test_matches(max_goal_7_matches, "7球", print_log)
            elif bet_option == "7球" and type == "最小":
                month, bet, win_count, win_amount, profit = back_test_matches(min_goal_7_matches, "7球", print_log)

            total_bet += bet
            total_win_count += win_count
            total_win_amount += win_amount

            # month record
            if (month in month_record.keys()):
                record = month_record[month]
            else:
                record = {"bet": 0, "win_amount": 0, "win_count": 0, "profit": 0}
            record["bet"] += bet
            record["win_count"] += win_count
            record["win_amount"] += win_amount
            record["profit"] = record["win_amount"] - record["bet"]
            month_record[month] = record

            if win_count > 0:
                max_gap_days = max(max_gap_days, gap_days)
                gap_days = 0
            else:
                gap_days += 1

            day_in_week += 1
            if day_in_week >= len(week_day):
                day_in_week = 0
            day_in_week_str = week_day[day_in_week]
            current_day_match_list.clear()
            current_day_match_list.append(m)

    profit = round(total_win_amount - total_bet, 2)
    print(
        f"\n===== {type} {bet_option} =====")
    print(
        f"总 下注金额:{total_bet} 赢金额:{round(total_win_amount, 2)} 赢次数:{total_win_count} 利润:{profit} 最大期数:{max_gap_days}")

    for k in month_record.keys():
        record = month_record[k]
        print(
            f"{k}月 下注:{record['bet']} 中次数:{record['win_count']} 中金额:{round(record['win_amount'], 2)} 利润:{round(record['profit'], 2)}")


def back_test_matches(matches, target_result, print_log):
    bet = 0
    win_amount = 0
    win_count = 0
    profit = 0

    for sm in matches:
        if target_result == "胜胜":
            ratio = sm.ww
        elif target_result == "胜平":
            ratio = sm.wd
        elif target_result == "胜负":
            ratio = sm.wl
        elif target_result == "平胜":
            ratio = sm.dw
        elif target_result == "平平":
            ratio = sm.dd
        elif target_result == "平负":
            ratio = sm.dl

        elif target_result == "负胜":
            ratio = sm.lw
        elif target_result == "负平":
            ratio = sm.ld
        elif target_result == "负负":
            ratio = sm.ll

        elif target_result == "0球":
            ratio = sm.goal_0
        elif target_result == "1球":
            ratio = sm.goal_1
        elif target_result == "2球":
            ratio = sm.goal_2
        elif target_result == "3球":
            ratio = sm.goal_3
        elif target_result == "4球":
            ratio = sm.goal_4
        elif target_result == "5球":
            ratio = sm.goal_5
        elif target_result == "6球":
            ratio = sm.goal_6
        elif target_result == "7球":
            ratio = sm.goal_7

        month = sm.game_date.month
        # if (month in month_record.keys()):
        #     record = month_record[month]
        # else:
        #     record = {"bet": 0, "win_amount": 0, "win_count": 0, "profit": 0}

        if ratio < 99:
            bet += 1
            winning = False
            if (target_result.endswith("球")):
                if int(target_result[:1]) == sm.goal_result:
                    winning = True
            elif (sm.half_result == target_result):
                winning = True

            if winning:
                win_count += 1
                win_amount += ratio
                profit = round(win_amount - bet, 2)
                if print_log:
                    print(
                        f"{sm.game_date.strftime('%Y-%m-%d')} +{ratio} {sm.no} {sm.home_team} vs {sm.away_team} 赛果：{sm.half_result}")
            else:
                profit = round(win_amount - bet, 2)
                if print_log:
                    print(
                        f"{sm.game_date.strftime('%Y-%m-%d')} -1 {sm.no} {sm.home_team} vs {sm.away_team} 赛果：{sm.half_result}")
        return month, bet, win_count, win_amount, profit


def pick_matches(matches):
    max_ww = 0
    min_ww = 999
    max_ww_matches = []
    min_ww_matches = []

    max_wd = 0
    min_wd = 999
    max_wd_matches = []
    min_wd_matches = []

    max_wl = 0
    min_wl = 999
    max_wl_matches = []
    min_wl_matches = []

    max_dw = 0
    min_dw = 999
    max_dw_matches = []
    min_dw_matches = []

    max_dd = 0
    min_dd = 999
    max_dd_matches = []
    min_dd_matches = []

    max_dl = 0
    min_dl = 999
    max_dl_matches = []
    min_dl_matches = []

    max_lw = 0
    min_lw = 999
    max_lw_matches = []
    min_lw_matches = []

    max_ld = 0
    min_ld = 999
    max_ld_matches = []
    min_ld_matches = []

    max_ll = 0
    min_ll = 999
    max_ll_matches = []
    min_ll_matches = []

    max_goal_0 = 0
    min_goal_0 = 999
    max_goal_0_matches = []
    min_goal_0_matches = []

    max_goal_1 = 0
    min_goal_1 = 999
    max_goal_1_matches = []
    min_goal_1_matches = []

    max_goal_2 = 0
    min_goal_2 = 999
    max_goal_2_matches = []
    min_goal_2_matches = []

    max_goal_3 = 0
    min_goal_3 = 999
    max_goal_3_matches = []
    min_goal_3_matches = []

    max_goal_4 = 0
    min_goal_4 = 999
    max_goal_4_matches = []
    min_goal_4_matches = []

    max_goal_5 = 0
    min_goal_5 = 999
    max_goal_5_matches = []
    min_goal_5_matches = []

    max_goal_6 = 0
    min_goal_6 = 999
    max_goal_6_matches = []
    min_goal_6_matches = []

    max_goal_7 = 0
    min_goal_7 = 999
    max_goal_7_matches = []
    min_goal_7_matches = []

    for deal_match in matches:
        # 胜胜
        if deal_match.ww < min_ww:
            min_ww = deal_match.ww
            min_ww_matches.clear()
            min_ww_matches.append(deal_match)
        elif deal_match.ww == min_ww:
            min_ww_matches.append(deal_match)

        if deal_match.ww > max_ww:
            max_ww = deal_match.ww
            max_ww_matches.clear()
            max_ww_matches.append(deal_match)
        elif deal_match.ww == max_ww:
            max_ww_matches.append(deal_match)

        # 胜平
        if deal_match.wd < min_wd:
            min_wd = deal_match.wd
            min_wd_matches.clear()
            min_wd_matches.append(deal_match)
        elif deal_match.wd == min_wd:
            min_wd_matches.append(deal_match)

        if deal_match.wd > max_wd:
            max_wd = deal_match.wd
            max_wd_matches.clear()
            max_wd_matches.append(deal_match)
        elif deal_match.wd == max_wd:
            max_wd_matches.append(deal_match)

        # 胜负
        if deal_match.wl < min_wl:
            min_wl = deal_match.wl
            min_wl_matches.clear()
            min_wl_matches.append(deal_match)
        elif deal_match.wl == min_wl:
            min_wl_matches.append(deal_match)

        if deal_match.wl > max_wl:
            max_wl = deal_match.wl
            max_wl_matches.clear()
            max_wl_matches.append(deal_match)
        elif deal_match.wl == max_wl:
            max_wl_matches.append(deal_match)

        # 平胜
        if deal_match.dw < min_dw:
            min_dw = deal_match.dw
            min_dw_matches.clear()
            min_dw_matches.append(deal_match)
        elif deal_match.dw == min_dw:
            min_dw_matches.append(deal_match)

        if deal_match.dw > max_dw:
            max_dw = deal_match.dw
            max_dw_matches.clear()
            max_dw_matches.append(deal_match)
        elif deal_match.dw == max_dw:
            max_dw_matches.append(deal_match)

        # 平平
        if deal_match.dd < min_dd:
            min_dd = deal_match.dd
            min_dd_matches.clear()
            min_dd_matches.append(deal_match)
        elif deal_match.dd == min_dd:
            min_dd_matches.append(deal_match)

        if deal_match.dd > max_dd:
            max_dd = deal_match.dd
            max_dd_matches.clear()
            max_dd_matches.append(deal_match)
        elif deal_match.dd == max_dd:
            max_dd_matches.append(deal_match)
        # 平负
        if deal_match.dl < min_dl:
            min_dl = deal_match.dl
            min_dl_matches.clear()
            min_dl_matches.append(deal_match)
        elif deal_match.dl == min_dl:
            min_dl_matches.append(deal_match)

        if deal_match.dl > max_dl:
            max_dl = deal_match.dl
            max_dl_matches.clear()
            max_dl_matches.append(deal_match)
        elif deal_match.dl == max_dl:
            max_dl_matches.append(deal_match)

        # 负胜
        if deal_match.lw < min_lw:
            min_lw = deal_match.lw
            min_lw_matches.clear()
            min_lw_matches.append(deal_match)
        elif deal_match.lw == min_lw:
            min_lw_matches.append(deal_match)

        if deal_match.lw > max_lw:
            max_lw = deal_match.lw
            max_lw_matches.clear()
            max_lw_matches.append(deal_match)
        elif deal_match.lw == max_lw:
            max_lw_matches.append(deal_match)

        # 负平
        if deal_match.ld < min_ld:
            min_ld = deal_match.ld
            min_ld_matches.clear()
            min_ld_matches.append(deal_match)
        elif deal_match.ld == min_ld:
            min_ld_matches.append(deal_match)

        if deal_match.ld > max_ld:
            max_ld = deal_match.ld
            max_ld_matches.clear()
            max_ld_matches.append(deal_match)
        elif deal_match.ld == max_ld:
            max_ld_matches.append(deal_match)

        # 负负
        if deal_match.ll < min_ll:
            min_ll = deal_match.ll
            min_ll_matches.clear()
            min_ll_matches.append(deal_match)
        elif deal_match.ll == min_ll:
            min_ll_matches.append(deal_match)

        if deal_match.ll > max_ll:
            max_ll = deal_match.ll
            max_ll_matches.clear()
            max_ll_matches.append(deal_match)
        elif deal_match.ll == max_ll:
            max_ll_matches.append(deal_match)

        # 0球
        if deal_match.goal_0 < min_goal_0:
            min_goal_0 = deal_match.goal_0
            min_goal_0_matches.clear()
            min_goal_0_matches.append(deal_match)
        elif deal_match.goal_0 == min_goal_0:
            min_goal_0_matches.append(deal_match)

        if deal_match.goal_0 > max_goal_0:
            max_goal_0 = deal_match.goal_0
            max_goal_0_matches.clear()
            max_goal_0_matches.append(deal_match)
        elif deal_match.goal_0 == max_goal_0:
            max_goal_0_matches.append(deal_match)

        # 1球
        if deal_match.goal_1 < min_goal_1:
            min_goal_1 = deal_match.goal_1
            min_goal_1_matches.clear()
            min_goal_1_matches.append(deal_match)
        elif deal_match.goal_1 == min_goal_1:
            min_goal_1_matches.append(deal_match)

        if deal_match.goal_1 > max_goal_1:
            max_goal_1 = deal_match.goal_1
            max_goal_1_matches.clear()
            max_goal_1_matches.append(deal_match)
        elif deal_match.goal_1 == max_goal_1:
            max_goal_1_matches.append(deal_match)

        # 2球
        if deal_match.goal_2 < min_goal_2:
            min_goal_2 = deal_match.goal_2
            min_goal_2_matches.clear()
            min_goal_2_matches.append(deal_match)
        elif deal_match.goal_2 == min_goal_2:
            min_goal_2_matches.append(deal_match)

        if deal_match.goal_2 > max_goal_2:
            max_goal_2 = deal_match.goal_2
            max_goal_2_matches.clear()
            max_goal_2_matches.append(deal_match)
        elif deal_match.goal_2 == max_goal_2:
            max_goal_2_matches.append(deal_match)

        # 3球
        if deal_match.goal_3 < min_goal_3:
            min_goal_3 = deal_match.goal_3
            min_goal_3_matches.clear()
            min_goal_3_matches.append(deal_match)
        elif deal_match.goal_3 == min_goal_3:
            min_goal_3_matches.append(deal_match)

        if deal_match.goal_3 > max_goal_3:
            max_goal_3 = deal_match.goal_3
            max_goal_3_matches.clear()
            max_goal_3_matches.append(deal_match)
        elif deal_match.goal_3 == max_goal_3:
            max_goal_3_matches.append(deal_match)

        # 4球
        if deal_match.goal_4 < min_goal_4:
            min_goal_4 = deal_match.goal_4
            min_goal_4_matches.clear()
            min_goal_4_matches.append(deal_match)
        elif deal_match.goal_4 == min_goal_4:
            min_goal_4_matches.append(deal_match)

        if deal_match.goal_4 > max_goal_4:
            max_goal_4 = deal_match.goal_4
            max_goal_4_matches.clear()
            max_goal_4_matches.append(deal_match)
        elif deal_match.goal_4 == max_goal_4:
            max_goal_4_matches.append(deal_match)

        # 5球
        if deal_match.goal_5 < min_goal_5:
            min_goal_5 = deal_match.goal_5
            min_goal_5_matches.clear()
            min_goal_5_matches.append(deal_match)
        elif deal_match.goal_5 == min_goal_5:
            min_goal_5_matches.append(deal_match)

        if deal_match.goal_5 > max_goal_5:
            max_goal_5 = deal_match.goal_5
            max_goal_5_matches.clear()
            max_goal_5_matches.append(deal_match)
        elif deal_match.goal_5 == max_goal_5:
            max_goal_5_matches.append(deal_match)

        # 6球
        if deal_match.goal_6 < min_goal_6:
            min_goal_6 = deal_match.goal_6
            min_goal_6_matches.clear()
            min_goal_6_matches.append(deal_match)
        elif deal_match.goal_6 == min_goal_6:
            min_goal_6_matches.append(deal_match)

        if deal_match.goal_6 > max_goal_6:
            max_goal_6 = deal_match.goal_6
            max_goal_6_matches.clear()
            max_goal_6_matches.append(deal_match)
        elif deal_match.goal_6 == max_goal_6:
            max_goal_6_matches.append(deal_match)

        # 7球
        if deal_match.goal_7 < min_goal_7:
            min_goal_7 = deal_match.goal_7
            min_goal_7_matches.clear()
            min_goal_7_matches.append(deal_match)
        elif deal_match.goal_7 == min_goal_7:
            min_goal_7_matches.append(deal_match)

        if deal_match.goal_7 > max_goal_7:
            max_goal_7 = deal_match.goal_7
            max_goal_7_matches.clear()
            max_goal_7_matches.append(deal_match)
        elif deal_match.goal_7 == max_goal_7:
            max_goal_7_matches.append(deal_match)

    return (max_ww_matches, min_ww_matches,
            max_wd_matches, min_wd_matches,
            max_wl_matches, min_wl_matches,
            max_dw_matches, min_dw_matches,
            max_dd_matches, min_dd_matches,
            max_dl_matches, min_dl_matches,
            max_lw_matches, min_lw_matches,
            max_ld_matches, min_ld_matches,
            max_ll_matches, min_ll_matches,
            max_goal_0_matches, min_goal_0_matches,
            max_goal_1_matches, min_goal_1_matches,
            max_goal_2_matches, min_goal_2_matches,
            max_goal_3_matches, min_goal_3_matches,
            max_goal_4_matches, min_goal_4_matches,
            max_goal_5_matches, min_goal_5_matches,
            max_goal_6_matches, min_goal_6_matches,
            max_goal_7_matches, min_goal_7_matches)


def analysis_data():
    total_bet = 0
    total_win_amount = 0
    total_win_count = 0
    profit = 0
    gap_days = 0
    max_gap_days = 0
    start_date = "2023-08-11"
    end_date = "2024-05-19"
    matches = read_test_data(start_date, end_date)
    data_map = {}
    for m in matches:
        if (m.league not in data_map.keys()):
            data_map[m.league] = {"count": 0,
                                  "match_100":[],
                                  "match_110": [],
                                  "match_120": [],
                                  "match_130": [],
                                  "match_140": [],
                                  "match_150": [],
                                  "match_160": [],
                                  "match_170": [],
                                  "match_180": [],
                                  "match_190": [],
                                  "match_other": [],

                                  "win_ratio_100_110": 0,
                                  "win_ratio_100_110_win": 0,
                                  "win_ratio_100_110_draw": 0,
                                  "win_ratio_100_110_lose": 0,

                                  "win_ratio_110_120": 0,
                                  "win_ratio_110_120_win": 0,
                                  "win_ratio_110_120_draw": 0,
                                  "win_ratio_110_120_lose": 0,

                                  "win_ratio_120_130": 0,
                                  "win_ratio_120_130_win": 0,
                                  "win_ratio_120_130_draw": 0,
                                  "win_ratio_120_130_lose": 0,

                                  "win_ratio_130_140": 0,
                                  "win_ratio_130_140_win": 0,
                                  "win_ratio_130_140_draw": 0,
                                  "win_ratio_130_140_lose": 0,

                                  "win_ratio_140_150": 0,
                                  "win_ratio_140_150_win": 0,
                                  "win_ratio_140_150_draw": 0,
                                  "win_ratio_140_150_lose": 0,

                                  "win_ratio_150_160": 0,
                                  "win_ratio_150_160_win": 0,
                                  "win_ratio_150_160_draw": 0,
                                  "win_ratio_150_160_lose": 0,

                                  "win_ratio_160_170": 0,
                                  "win_ratio_160_170_win": 0,
                                  "win_ratio_160_170_draw": 0,
                                  "win_ratio_160_170_lose": 0,

                                  "win_ratio_170_180": 0,
                                  "win_ratio_170_180_win": 0,
                                  "win_ratio_170_180_draw": 0,
                                  "win_ratio_170_180_lose": 0,

                                  "win_ratio_180_190": 0,
                                  "win_ratio_180_190_win": 0,
                                  "win_ratio_180_190_draw": 0,
                                  "win_ratio_180_190_lose": 0,

                                  "win_ratio_190_200": 0,
                                  "win_ratio_190_200_win": 0,
                                  "win_ratio_190_200_draw": 0,
                                  "win_ratio_190_200_lose": 0,

                                  "win_ratio_other": 0,
                                  "win_ratio_other_win": 0,
                                  "win_ratio_other_draw": 0,
                                  "win_ratio_other_lose": 0}

        data = data_map[m.league]

        data["count"] += 1
        if (1 <= m.win and m.win < 1.1):
            data["match_100"].append(m)
            data["win_ratio_100_110"] += 1
            if m.result == 3:
                data["win_ratio_100_110_win"] += 1
            elif m.result == 1:
                data["win_ratio_100_110_draw"] += 1
            else:
                data["win_ratio_100_110_lose"] += 1

        elif (1.1 <= m.win and m.win < 1.2):
            data["match_110"].append(m)
            data["win_ratio_110_120"] += 1
            if m.result == 3:
                data["win_ratio_110_120_win"] += 1
            elif m.result == 1:
                data["win_ratio_110_120_draw"] += 1
            else:
                data["win_ratio_110_120_lose"] += 1

        elif (1.2 <= m.win and m.win < 1.3):
            data["match_120"].append(m)
            data["win_ratio_120_130"] += 1
            if m.result == 3:
                data["win_ratio_120_130_win"] += 1
            elif m.result == 1:
                data["win_ratio_120_130_draw"] += 1
            else:
                data["win_ratio_120_130_lose"] += 1

        elif (1.3 <= m.win and m.win < 1.4):
            data["match_130"].append(m)
            data["win_ratio_130_140"] += 1
            if m.result == 3:
                data["win_ratio_130_140_win"] += 1
            elif m.result == 1:
                data["win_ratio_130_140_draw"] += 1
            else:
                data["win_ratio_130_140_lose"] += 1

        elif (1.4 <= m.win and m.win < 1.5):
            data["match_140"].append(m)
            data["win_ratio_140_150"] += 1
            if m.result == 3:
                data["win_ratio_140_150_win"] += 1
            elif m.result == 1:
                data["win_ratio_140_150_draw"] += 1
            else:
                data["win_ratio_140_150_lose"] += 1

        elif (1.5 <= m.win and m.win < 1.6):
            data["match_150"].append(m)
            data["win_ratio_150_160"] += 1
            if m.result == 3:
                data["win_ratio_150_160_win"] += 1
            elif m.result == 1:
                data["win_ratio_150_160_draw"] += 1
            else:
                data["win_ratio_150_160_lose"] += 1

        else:
            data["match_other"].append(m)
            data["win_ratio_other"] += 1
            if m.result == 3:
                data["win_ratio_other_win"] += 1
            elif m.result == 1:
                data["win_ratio_other_draw"] += 1
            else:
                data["win_ratio_other_lose"] += 1

        data_map[m.league] = data

    data_map = dict(sorted(data_map.items(), key=lambda kv: -kv[1]["count"]))

    for league in data_map.keys():
        if (league not in ["英超","西甲"]):
            continue
        data = data_map[league]

        win_100_percent = 0 if data["win_ratio_100_110_win"] == 0 else round(
            data["win_ratio_100_110_win"] * 100 / data["win_ratio_100_110"], 1)
        win_110_percent = 0 if data["win_ratio_110_120_win"] == 0 else round(
            data["win_ratio_110_120_win"] * 100 / data["win_ratio_110_120"], 1)
        win_120_percent = 0 if data["win_ratio_120_130_win"] == 0 else round(
            data["win_ratio_120_130_win"] * 100 / data["win_ratio_120_130"], 1)
        win_130_percent = 0 if data["win_ratio_130_140_win"] == 0 else round(
            data["win_ratio_130_140_win"] * 100 / data["win_ratio_130_140"], 1)
        win_140_percent = 0 if data["win_ratio_140_150_win"] == 0 else round(
            data["win_ratio_140_150_win"] * 100 / data["win_ratio_140_150"], 1)
        win_150_percent = 0 if data["win_ratio_150_160_win"] == 0 else round(
            data["win_ratio_150_160_win"] * 100 / data["win_ratio_150_160"], 1)

        draw_100_percent = 0 if data["win_ratio_100_110_draw"] == 0 else round(
            data["win_ratio_100_110_draw"] * 100 / data["win_ratio_100_110"], 1)
        draw_110_percent = 0 if data["win_ratio_110_120_draw"] == 0 else round(
            data["win_ratio_110_120_draw"] * 100 / data["win_ratio_110_120"], 1)
        draw_120_percent = 0 if data["win_ratio_120_130_draw"] == 0 else round(
            data["win_ratio_120_130_draw"] * 100 / data["win_ratio_120_130"], 1)
        draw_130_percent = 0 if data["win_ratio_130_140_draw"] == 0 else round(
            data["win_ratio_130_140_draw"] * 100 / data["win_ratio_130_140"], 1)
        draw_140_percent = 0 if data["win_ratio_140_150_draw"] == 0 else round(
            data["win_ratio_140_150_draw"] * 100 / data["win_ratio_140_150"], 1)
        draw_150_percent = 0 if data["win_ratio_150_160_draw"] == 0 else round(
            data["win_ratio_150_160_draw"] * 100 / data["win_ratio_150_160"], 1)

        lose_100_percent = 0 if data["win_ratio_100_110_lose"] == 0 else round(
            data["win_ratio_100_110_lose"] * 100 / data["win_ratio_100_110"], 1)
        lose_110_percent = 0 if data["win_ratio_110_120_lose"] == 0 else round(
            data["win_ratio_110_120_lose"] * 100 / data["win_ratio_110_120"], 1)
        lose_120_percent = 0 if data["win_ratio_120_130_lose"] == 0 else round(
            data["win_ratio_120_130_lose"] * 100 / data["win_ratio_120_130"], 1)
        lose_130_percent = 0 if data["win_ratio_130_140_lose"] == 0 else round(
            data["win_ratio_130_140_lose"] * 100 / data["win_ratio_130_140"], 1)
        lose_140_percent = 0 if data["win_ratio_140_150_lose"] == 0 else round(
            data["win_ratio_140_150_lose"] * 100 / data["win_ratio_140_150"], 1)
        lose_150_percent = 0 if data["win_ratio_150_160_lose"] == 0 else round(
            data["win_ratio_150_160_lose"] * 100 / data["win_ratio_150_160"], 1)

        print("==========")
        print(f'{league} 场次:{data["count"]} \n'
              f'胜赔率1.0-1.1 {data["win_ratio_100_110"]}场 [{win_100_percent}% {draw_100_percent}% {lose_100_percent}%] [{data["win_ratio_100_110_win"]} {data["win_ratio_100_110_draw"]} {data["win_ratio_100_110_lose"]}]\n'
              f'胜赔率1.1-1.2 {data["win_ratio_110_120"]}场 [{win_110_percent}% {draw_110_percent}% {lose_110_percent}%] [{data["win_ratio_110_120_win"]} {data["win_ratio_110_120_draw"]} {data["win_ratio_110_120_lose"]}]\n'
              f'胜赔率1.2-1.3 {data["win_ratio_120_130"]}场 [{win_120_percent}% {draw_120_percent}% {lose_120_percent}%] [{data["win_ratio_120_130_win"]} {data["win_ratio_120_130_draw"]} {data["win_ratio_120_130_lose"]}]\n'
              f'胜赔率1.3-1.4 {data["win_ratio_130_140"]}场 [{win_130_percent}% {draw_130_percent}% {lose_130_percent}%] [{data["win_ratio_130_140_win"]} {data["win_ratio_130_140_draw"]} {data["win_ratio_130_140_lose"]}]\n'
              f'胜赔率1.4-1.5 {data["win_ratio_140_150"]}场 [{win_140_percent}% {draw_140_percent}% {lose_140_percent}%] [{data["win_ratio_140_150_win"]} {data["win_ratio_140_150_draw"]} {data["win_ratio_140_150_lose"]}]\n'
              f'胜赔率1.5-1.6 {data["win_ratio_150_160"]}场 [{win_150_percent}% {draw_150_percent}% {lose_150_percent}%] [{data["win_ratio_150_160_win"]} {data["win_ratio_150_160_draw"]} {data["win_ratio_150_160_lose"]}]\n'

              f'胜赔率其他 {data["win_ratio_other"]}场 [{data["win_ratio_other_win"]} {data["win_ratio_other_draw"]} {data["win_ratio_other_lose"]}]\n'
              )

        match_100 = data["match_100"]
        match_110 = data["match_110"]
        match_120 = data["match_120"]
        match_130 = data["match_130"]
        match_140 = data["match_140"]
        match_150 = data["match_150"]
        match_160 = data["match_160"]
        match_170 = data["match_170"]
        match_180 = data["match_180"]
        match_190 = data["match_190"]
        match_other = data["match_other"]
        all_matches={"1.0-1.1":match_100,
                 "1.1-1.2":match_110,
                 "1.2-1.3":match_120,
                 "1.3-1.4":match_130,
                 "1.4-1.5":match_140,
                 "1.5-1.6":match_150,
                 "1.6-1.7":match_160,
                 "1.7-1.8":match_170,
                 "1.8-1.9":match_180,
                 "1.9-2.0":match_190,
                 "other":match_other}

        for k in all_matches.keys():
            matches = all_matches[k]
            print(f"{k}")
            for m in matches:
                if m.result==3:
                    continue
                print(f"{m.home_team} vs {m.away_team} 结果：{m.result}")





if __name__ == '__main__':
    # backtest_half2("胜负", "最大",True)
    # backtest_half2("胜负", "最小",True)
    analysis_data()
